package com.springbootnetty.utils;

import com.google.common.collect.Maps;
import com.springbootnetty.handler.BaseHandler;
import com.springbootnetty.handler.BenType;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;


/**
 * 向spring中添加自定义ben
 *  benMap 记录ben
 * */
@Component
@SuppressWarnings("unchecked")
public class SpringBenUtil implements ApplicationContextAware , BeanFactoryPostProcessor {

    //指定扫描包
    private static final String HANDLER_PACKAGE = "com.springbootnetty";
    //上下文
    private static ApplicationContext applicationContext;

    private static Map<Integer, Class> benMap;

    /**
     * 扫描指定包下 有BenType 注解的类
     * 加入spring管理
     * */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
         benMap = Maps.newHashMapWithExpectedSize(3);
        ClassScanerUtil.scan(HANDLER_PACKAGE, BenType.class).forEach(clazz -> {
            // 获取注解中的类型值
            int type = clazz.getAnnotation(BenType.class).value();
            // 将注解中的类型值作为key，对应的类作为value，保存在Map中
            benMap.put(type, clazz);
        });
        // 初始化HandlerContext，将其注册到spring容器中
        SpringBenUtil context = new SpringBenUtil(benMap);
        beanFactory.registerSingleton(SpringBenUtil.class.getName(), context);
        System.out.println("自定义ben注入完成.................."+context+benMap.toString());
    }






    /**
     * 获取spring 的上下文
     * */
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        if (applicationContext == null) {
            applicationContext = context;
        }
    }


    public SpringBenUtil() {
    }


    public SpringBenUtil(Map<Integer, Class> handlerMap) {
        this.benMap = handlerMap;
    }


    /**
     * 根据元注解类型获取
     * benMap中的类
     *
     *
     * */
    public BaseHandler getBean(Integer type){
        Class clazz = benMap.get(type);
        if (clazz == null) {
            return null;
        }
        return (BaseHandler) getBean(clazz);
    }


    /**
     * 根据class类型获取ben
     *
     *
     * */
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }



}
